// 这个中间件作用是路由地址的权限控制
import jwt = require('jsonwebtoken');

const isAction = (actionRights: any, path: string, method: string) => {
  const reg = new RegExp(`^${actionRights.rightsPath}(/[0-9]*)?$`, 'i');
  if (reg.test(path) && actionRights.rightsMethod === method) return true;
  if (actionRights.children) {
    for (let i = 0; i < actionRights.children.length; i++) {
      const item = actionRights.children[i];
      if (isAction(item, path, method)) return true;
    }
  }
  return false;
};

// 得到用户请求的权限
const getActionRights = ctx => {
  const userInfo = ctx.session.user;
  if (!userInfo) return null;
  // eslint-disable-next-line array-callback-return
  const actionRights = userInfo.rightsTree.filter((rights: any) => {
    if (rights.rightsType === 'action') return rights;
  });
  return actionRights[0];
};

let actionRights;
// _options 加了 _ 代表没有用到
module.exports = (_options, app) => {
  return async function(ctx, next) {
    // /api/v1/users
    // /api/v1/users?page=1&pageSize=5;
    let curPath = ctx.url.toLowerCase();
    const curMethod = ctx.request.method.toLowerCase();
    // 如果不是以 /api/v1 开头的请求, 例如登录注册等等就直接放行
    if (!curPath.startsWith('/api/v1')) {
      // 不需要权限控制
      await next();
      return;
    }
    // 如果没有用户请求权限则先获取
    if (!actionRights) {
      actionRights = getActionRights(ctx);
    }
    if (!actionRights) {
      ctx.error(400, '没有权限');
      return;
    }
    const idx = curPath.indexOf('?');
    if (idx !== -1) {
      // 以 ? 分割 去掉请求地址上 ? 后面的东西
      curPath = curPath.split('?')[0];
      // curPath = curPath.substr(0, idx);
    }
    const flag = isAction(actionRights, curPath, curMethod);
    if (flag) {
      // 🔔注意点: 在设置cookies时如果设置了 signed: false 则获取的时候也要设置，避免获取不到cookie值

      const token = ctx.cookies.get('token', {
        signed: false,
      });

      if (token) {
        try {
          // 验证JWT令牌是否正确
          await jwt.verify(token, app.config.keys);
          await next();
        } catch (e) {
          ctx.error(400, '没有权限');
        }
      } else {
        ctx.error(400, '没有权限');
      }
    } else {
      ctx.error(400, '没有权限');
    }
    // 1.获取需要权限控制的路由地址
    // const authUrls = options.authUrls;

    // 2.判断当前请求的路由地址是否需要权限控制
    // if (authUrls.includes(ctx.url)) {

    // 需要权限控制
    // 3.获取客户端传递过来的JWT令牌
    // const token = ctx.get('authorization');
    // 🔔注意点: 在设置cookies时如果设置了 signed: false 则获取的时候也要设置，避免获取不到cookie值

    // const token = ctx.cookies.get('token', {
    //     signed: false,
    //   });
    // 4.判断客户端有没有传递JWT令牌
    //   if (token) {
    //     try {
    //       // 验证JWT令牌是否正确
    //       await jwt.verify(token, app.config.keys);
    //       await next();
    //     } catch (e) {
    //       ctx.error(400, '没有权限');
    //     }
    //   } else {
    //     ctx.error(400, '没有权限');
    //   }
    // } else {
    // 不需要权限
    //   await next();
    // }
  };
};
